﻿'
' Boogaloo® - http://www.mindfly.com
' Copyright (c) 2009
' by Mindfly, Inc.
'
' Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
' documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
' the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
' to permit persons to whom the Software is furnished to do so, subject to the following conditions:
'
' The above copyright notice and this permission notice shall be included in all copies or substantial portions 
' of the Software.
'
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
' INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
' DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
' SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
' SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
' WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
' THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Imports Boogaloo.Base
Imports Boogaloo.Core.UI
Imports Boogaloo.Core.DAL
Imports Boogaloo.Syndication.XmlRpc

Imports System.Net
Imports System.Xml
Imports System.IO
Imports System.Text

Namespace BLL

    ''' <summary>
    ''' Ping various blog ping services and provides methods to administrate the
    ''' ping services to be pinged
    ''' </summary>
    ''' <remarks>Only allows pings if the url has not been pinged within the configured cache interval</remarks>
    Public Class PingService
        Inherits PingServiceBase

        Public Sub New( _
         ByVal ping_service_id As Integer, _
         ByVal uri As String, _
         ByVal created_date As DateTime, _
         ByVal last_modified_date As DateTime, _
         ByVal last_modified_by As String)


            Me.ping_service_id = ping_service_id
            Me.uri = uri
            Me.created_date = created_date
            Me.last_modified_date = last_modified_date
            Me.last_modified_by = last_modified_by

        End Sub

        ''' <summary>
        ''' Sends a ping to various ping services asynchronously.
        ''' </summary>
        ''' <remarks>Adaptation of BlogEngine.NET method with the same name</remarks>
        Public Shared Sub Send(ByVal url As Uri)


            Dim services As List(Of PingService) = GetPingServices()
            Dim service As PingService = Nothing
            For Each service In services

                Dim key As String = "pingservice_pingservice_send_" & service.uri & "_" & url.ToString
                If PingServiceBase.ProviderSettings.EnableCaching = False Or PingServiceBase.Cache(key) Is Nothing Then
                    PingService.Execute(service.uri, url)
                    PingServiceBase.CacheData(key, "Already Pinged")
                End If

            Next

        End Sub

        ''' <summary>
        ''' Creates a web request and invokes the response asynchronous.
        ''' </summary>
        ''' <remarks>Adaptation of BlogEngine.NET method with the same name</remarks>
        Public Shared Sub Execute(ByVal service As String, ByVal url As Uri)

            Try
                Dim req As New XmlRpcRequest()
                req.methodName = "weblogUpdates.ping"
                req.params.Add(New XmlRpcValue(Groove.admin_root.name, XmlRpcValue.ValueType.str))
                req.params.Add(New XmlRpcValue(url.ToString(), XmlRpcValue.ValueType.str))
                Dim service_uri As New Uri(service, UriKind.Absolute)
                Dim resp As XmlRpcResponse = req.Send(service_uri)

            Catch ex As Exception
                If CoreSettings.EnableLogging Then EventLogger.Write(String.Format("Failed to ping {0} - {1}", service, ex.Message), "PingService.Exectue", True)
            End Try

        End Sub


        Public Shared Function HasBeenPinged(ByVal url As Uri) As Boolean
            Dim key As String = "pingservice_ping_" & url.ToString
            Return PingServiceBase.Cache(key) Is Nothing
        End Function


#Region "PingService Administration"

        ''' <summary>
        ''' Gets an PingService
        ''' </summary>
        ''' <param name="ping_service_id">Integer (PK of database record)</param>
        ''' <remark>rss - 4/19/2009</remark>
        Public Shared Function GetPingService(ByVal ping_service_id As Integer) As PingService
            Dim key As String = "pingservice_pingservice_" & ping_service_id.ToString
            Dim instance As PingService = Nothing
            If PingServiceBase.ProviderSettings.EnableCaching And BizObject.Cache(key) IsNot Nothing Then
                instance = CType(BizObject.Cache(key), PingService)
            Else
                instance = GetPingServiceFromPingServiceDetails(CoreProvider.PingService.GetPingService(ping_service_id))
                PingServiceBase.CacheData(key, instance)
            End If
            Return instance
        End Function

        ''' <summary>
        ''' Gets a list of all PingServices
        ''' </summary>
        ''' <remark>rss - 4/19/2009</remark>
        Public Shared Function GetPingServices() As List(Of PingService)
            Dim key As String = "pingservice_pingservices"
            Dim pingservices As List(Of PingService) = Nothing
            If PingServiceBase.ProviderSettings.EnableCaching And BizObject.Cache(key) IsNot Nothing Then
                pingservices = CType(BizObject.Cache(key), List(Of PingService))
            Else
                pingservices = GetPingServiceCollectionFromPingServiceDetailsList(CoreProvider.PingService.GetPingServices())
                PingServiceBase.CacheData(key, pingservices)
            End If
            Return pingservices
        End Function


        ''' <summary>
        ''' Inserts a new PingService
        ''' </summary>
        ''' <returns>PK, Integer</returns>
        ''' <remark>rss - 4/19/2009</remark>
        Public Shared Function InsertPingService(ByVal uri As String) As Integer

            Dim details As New PingServiceDetails(0, uri, Nothing, Nothing, PingServiceBase.CurrentUserName)

            Dim ret As Integer = CoreProvider.PingService.InsertPingService(details)

            BizObject.PurgeCacheItems("pingservice_pingservice")
            Return ret
        End Function

        ''' <summary>
        ''' Updates a PingService
        ''' </summary>
        ''' <returns>Boolean (success)</returns>
        ''' <remark>rss - 4/19/2009</remark>
        Public Shared Function UpdatePingService(ByVal ping_service_id As Integer, ByVal uri As String) As Boolean

            Dim details As New PingServiceDetails(ping_service_id, uri, Nothing, Nothing, PingServiceBase.CurrentUserName)

            Dim ret As Boolean = CoreProvider.PingService.UpdatePingService(details)

            BizObject.PurgeCacheItems("pingservice_pingservice")
            Return ret
        End Function

        ''' <summary>
        ''' Updates the current instance of PingService
        ''' </summary>
        ''' <returns>Boolean (success)</returns>
        ''' <remark>rss - 4/19/2009</remark>
        Public Function Update() As Boolean
            Return UpdatePingService(Me.ping_service_id, Me.uri)
        End Function

        ''' <summary>
        ''' Deletes a PingService
        ''' </summary>
        ''' <returns>Boolean (success)</returns>
        ''' <remark>rss - 4/19/2009</remark>
        Public Shared Function DeletePingService(ByVal ping_service_id As Integer) As Boolean
            Dim ret As Boolean = CoreProvider.PingService.DeletePingService(ping_service_id)

            Dim ev As New RecordDeletedEvent("PingService", ping_service_id, Nothing)
            ev.Raise()

            BizObject.PurgeCacheItems("pingservice_pingservice")
            Return ret
        End Function

        ''' <summary>
        ''' Deletes the current instance of PingService
        ''' </summary>
        ''' <returns>Boolean (success)</returns>
        ''' <remark>rss - 4/19/2009</remark>
        Public Function Delete() As Boolean
            Dim success As Boolean = DeletePingService(Me.ping_service_id)
            If success Then
                Me.ping_service_id = 0
            End If
            Return success
        End Function

        ''' <summary>
        ''' Creates a collection of PingService from a list of PingServiceDetails
        ''' </summary>
        ''' <param name="recordset">List(Of PingServiceDetails)</param>
        ''' <remark>rss - 4/19/2009</remark>
        Private Shared Function GetPingServiceCollectionFromPingServiceDetailsList(ByVal recordset As List(Of PingServiceDetails)) As List(Of PingService)

            Dim pingservices As New List(Of PingService)
            Dim record As PingServiceDetails = Nothing

            For Each record In recordset
                pingservices.Add(GetPingServiceFromPingServiceDetails(record))
            Next

            Return pingservices

        End Function

        ''' <summary>
        ''' Creates PingService from PingServiceDetails
        ''' </summary>
        ''' <param name="record">PingServiceDetails</param>
        ''' <remark>rss - 4/19/2009</remark>
        Private Shared Function GetPingServiceFromPingServiceDetails(ByVal record As PingServiceDetails) As PingService

            If record IsNot Nothing Then
                Return New PingService(record.ping_service_id, record.uri, record.created_date, record.last_modified_date, _
                 record.last_modified_by)
            Else
                Return Nothing
            End If

        End Function

#End Region

#Region "Properties and Member Data"

        Private _ping_service_id As Integer
        Public Property ping_service_id() As Integer
            Get
                Return _ping_service_id
            End Get
            Set(ByVal value As Integer)
                _ping_service_id = value
            End Set
        End Property

        Private _uri As String
        Public Property uri() As String
            Get
                Return _uri
            End Get
            Set(ByVal value As String)
                _uri = value
            End Set
        End Property


#End Region

    End Class


End Namespace
